﻿using MLSharp.Classification;

namespace MLSharp.See5
{
	/// <summary>
	/// A See5-based rule-set classifier factory.
	/// </summary>
	public class See5RuleSetFactory : See5, IClassifierFactory
	{
		#region Public Constructors

		/// <summary>
		/// Creates a factory using See5 paths specified by the application
		/// configuration file and the default options.
		/// </summary>
		public See5RuleSetFactory() : this (new See5Options())
		{
			
		}

		/// <summary>
		/// Creates a factory using See5 paths specified by the application
		/// configuration file and the specified construction options.
		/// </summary>
		/// <param name="options">The See5 options.</param>
		public See5RuleSetFactory(See5Options options) : base(options)
		{
			
		}

		/// <summary>
		/// Creates a factory using the specified See5 paths.
		/// </summary>
		/// <param name="see5XPath">The path to the See5X executable.</param>
		/// <param name="see5SamPath">Te path to the See5Sam executable.</param>
		/// <param name="workingDirectory">The working directory.</param>
		public See5RuleSetFactory(string see5XPath, string see5SamPath, string workingDirectory)
			: base(see5XPath, see5SamPath, workingDirectory)
		{
			
		}

		#endregion

		#region Public Methods

		/// <summary>
		/// Builds a See5 ruleset from the specified training data that will predict the 
		/// specified attribute.
		/// </summary>
		/// <param name="trainingData">The training data.</param>
		/// <returns>A <see cref="IRuleSet"/> that can be used to classify new instances.</returns>
		public IRuleSet BuildRuleSet(IDataSet trainingData)
		{
			//These values are generated by the training process and are needed to construct
			//the result decision tree.
			string stemName, targetAttributeName;

			TrainSee5(trainingData, true, out stemName, out targetAttributeName);

			IRuleSet ruleSet = new See5RuleSet(stemName, targetAttributeName, See5SamPath, See5WorkingDirectory);

			return ruleSet;
		}

		#endregion

		#region IClassifierFactory Implementation

		/// <summary>
		/// Routes to <see cref="BuildRuleSet"/>.
		/// </summary>
		/// <param name="trainingData"></param>
		/// <returns></returns>
		IClassifier IClassifierFactory.BuildClassifier(IDataSet trainingData)
		{
			return BuildRuleSet(trainingData);
		}

		/// <summary>
		/// Wrapper for Options.
		/// </summary>
		object IClassifierFactory.Options
		{
			get { return this.Options; }
		}

		#endregion
	}
}
